feat(payouts): surface vop response - #2074
Merged
Merged
Conversation
14 tasks
Auto-applied by CI: - cargo +nightly fmt --all - make -C sdk generate (if applicable) - make docs (if applicable) This commit was automatically generated by GitHub Actions.
deepanshu-iiitu
requested changes
Aug 7, 2026
Sakilmostak
reviewed
Aug 7, 2026
Auto-applied by CI: - cargo +nightly fmt --all - make -C sdk generate (if applicable) - make docs (if applicable) This commit was automatically generated by GitHub Actions.
Sakilmostak
reviewed
Aug 11, 2026
Sakilmostak
reviewed
Aug 11, 2026
…bility_reference_id
Sakilmostak
previously approved these changes
Aug 11, 2026
Sakilmostak
previously approved these changes
Aug 11, 2026
AkshayaFoiger
previously approved these changes
Aug 11, 2026
heykulthe
dismissed stale reviews from AkshayaFoiger and Sakilmostak
via
August 11, 2026 14:20
d9fe997
AmitsinghTanwar007
approved these changes
Aug 11, 2026
deepanshu-iiitu
approved these changes
Aug 11, 2026
Sakilmostak
approved these changes
Aug 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Surfaces Deutsche Bank's Verification-of-Payee (VoP) outcome on the payout eligibility response, so the caller can tell why a payee was refused and can reconcile the check afterwards.
Motivation and Context
A VoP refusal was previously indistinguishable from any other ineligible payee, the caller got a status and nothing else, so a merchant could not be told whether the IBAN failed to match the payee name, or the payee simply could not be checked.
NMTCandNOAPnow carry the verdict and Deutsche Bank's own explanation.Additional Changes
How did you test it?
Payout Create Response:
Payouts that result in VOP MTCH/CMTC result in additional info being surfaced to merchant in
metadatawhilst if it's a NMTC/NOAP,error_codeanderror_messagefields are populated.Create Payout Response (CMTC case):
{ "payout_id": "payout_dcTH1SFAsaRkixQitBss", "merchant_id": "merchant_1786014217", "merchant_order_reference_id": null, "amount": 101, "currency": "EUR", "connector": "deutschebank", "payout_type": "bank", "payout_method_data": { "bank": { "iban": "DE945************80002", "bank_name": "Deutsche Bank", "bank_country_code": "DE", "bank_city": null, "bic": "DEU*****237", "account_holder_name": "John Doe" } }, "source_bank_data": { "iban": "DE991************89001", "bank_name": null, "bank_country_code": null, "bank_city": null, "bic": "DEU*****237", "account_holder_name": "ABC Inc." }, "billing": { "address": { "city": "Frankfurt", "country": "DE", "line1": "Taunusanlage 12", "line2": null, "line3": null, "zip": "60325", "state": "HE", "first_name": "John", "last_name": "Doe", "origin_zip": null }, "phone": null, "email": null }, "auto_fulfill": true, "customer_id": "payout_customer121", "customer": { "id": "payout_customer121", "name": "John Doe", "email": "payout_customer@example.com", "phone": "999999999", "phone_country_code": "+49", "customer_document_details": null }, "client_secret": "payout_payout_dcTH1SFAsaRkixQitBss_secret_hZxcgLlpCZkJ9h1T8oRd", "return_url": null, "business_country": null, "business_label": null, "description": "any-purpose", "billing_descriptor": null, "entity_type": "Individual", "recurring": false, "metadata": { "vop_status": "CMTC", "additional_info": "The IBAN almost matches the name of the payee. This is the name of the account holder that belongs to the IBAN: CRON HOLDING GMBH. If you authorize the order anyway, this may result in the money being transferred to a payment account whose owner is not the payee you specified.", "eligibility_reference_id": "65992296-71d9-58fa-bc79-3f159e4a33bf" }, "merchant_connector_id": "mca_l9oDd6NGEAsvyptN4H3C", "status": "pending", "error_message": null, "error_code": null, "profile_id": "pro_jaLf7s7GauSiowdxrCEY", "created": "2026-08-06T22:38:26.592Z", "connector_transaction_id": "4EA1FDCFE05957C8BBEBCFF7D98B1BD6", "priority": null, "payout_link": null, "email": "payout_customer@example.com", "name": "John Doe", "phone": "999999999", "phone_country_code": "+49", "unified_code": null, "unified_message": null, "payout_method_id": null }Get Payout Response (NMTC case)
{ "payout_id": "payout_7AKlp8jmxZtCHm6iGuQX", "merchant_id": "merchant_1786014217", "merchant_order_reference_id": null, "amount": 101, "currency": "EUR", "connector": "deutschebank", "payout_type": "bank", "payout_method_data": { "bank": { "iban": "DE945************80002", "bank_name": "Deutsche Bank", "bank_country_code": "DE", "bank_city": null, "bic": "DEU*****237", "account_holder_name": "John Doe" } }, "source_bank_data": { "iban": "DE712************40602", "bank_name": null, "bank_country_code": null, "bank_city": null, "bic": "DEU*****237", "account_holder_name": "ABC Inc." }, "billing": { "address": { "city": "Frankfurt", "country": "DE", "line1": "Taunusanlage 12", "line2": null, "line3": null, "zip": "60325", "state": "HE", "first_name": "John", "last_name": "Doe", "origin_zip": null }, "phone": null, "email": null }, "auto_fulfill": true, "customer_id": "payout_customer121", "customer": { "id": "payout_customer121", "name": "John Doe", "email": "payout_customer@example.com", "phone": "999999999", "phone_country_code": "+49", "customer_document_details": null }, "client_secret": "payout_payout_7AKlp8jmxZtCHm6iGuQX_secret_tFD6wiKLSsMdG8x2xnXR", "return_url": null, "business_country": null, "business_label": null, "description": "any-purpose", "billing_descriptor": null, "entity_type": "Individual", "recurring": false, "metadata": { "eligibility_reference_id": "29d8b78b-eb88-5f4b-b126-9bdf42b4b921" }, "merchant_connector_id": "mca_l9oDd6NGEAsvyptN4H3C", "status": "not_permitted", "error_message": "The IBAN does not match the name of the payee. If you authorize the order anyway, this may result in the money being transferred to a payment account whose owner is not the payee you specified.", "error_code": "NMTC", "profile_id": "pro_jaLf7s7GauSiowdxrCEY", "created": "2026-08-06T22:41:41.695Z", "connector_transaction_id": null, "priority": null, "payout_link": null, "email": "payout_customer@example.com", "name": "John Doe", "phone": "999999999", "phone_country_code": "+49", "unified_code": null, "unified_message": null, "payout_method_id": null }